package com.angel.webapp.keyValue;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import com.angel.common.helpers.StringHelper;
import com.angel.common.keyValue.KeyValue;
import com.angel.common.keyValue.KeyValueResult;
import com.angel.common.keyValue.impl.KeyValueImpl;

/**
 * @author William
 * @since 03/February/2009
 */
public class SearchParametersKeyValueResult implements KeyValueResult{

    private Map<String, String> mapParameters;

    public SearchParametersKeyValueResult(String parameters, String parameterSeparator){
        super();
        mapParameters = convertParameterToMap(parameters, parameterSeparator);
    }

    /**
     * Convierte un string con parametros (clave=valor) separados por un "parameterSeparator" en un objeto map.
     *
     * @param stringParameters   string con los parametros (clave=valor) separador con parameterSeparator.
     * @param parameterSeparator string que separa los parametros.
     * @return un objeto map con <clave,valor>.
     */
    private synchronized static Map<String, String> convertParameterToMap(String stringParameters, String parameterSeparator) {
        Map<String, String> parameters = new HashMap<String, String>();
        String[] parametersPairs = stringParameters.split(parameterSeparator);
        for (String keyValueString : parametersPairs) {
            String[] keyValue = keyValueString.split("=");
            if (keyValue != null) {
                if (keyValue.length == 2) {
                    parameters.put(keyValue[0], keyValue[1]);
                }
            }
        }
        return parameters;
    }

    public Object getResultFor(Object o) {
        return this.mapParameters.get(o.toString());
    }

    public Object getResultNullSafeFor(Object o) {
        Object value = this.getResultFor(o);
        return value != null ? value.toString(): StringHelper.EMPTY_STRING;
    }

    public Object getResultNullSafeFor(Object o, Object o1) {
        Object value = this.getResultFor(o);
        return value != null ? value.toString(): o1;
    }

    @SuppressWarnings({"unchecked"})
    public <T> Collection<T> findAllResults() {
        return (Collection<T>) mapParameters.values();
    }

    @SuppressWarnings({"unchecked"})
    public <T> Collection<T> findAllKeys() {
        return (Collection<T>) mapParameters.keySet();
    }

    public Long resultSize() {
        return new Long(mapParameters.size());
    }

    public Boolean hasResult() {
        return this.resultSize() > 0;
    }

    public Boolean hasResultSize(Long aResultSize) {
        return this.resultSize().longValue() == aResultSize.longValue();
    }

    public void addKeyValueResult(KeyValueResult keyValueResult) {
        for(Object key: keyValueResult.findAllKeys()){
            mapParameters.put(key.toString(), keyValueResult.getResultFor(key).toString());
        }
    }

    public <T extends KeyValue> void addAll(Collection<T> ts) {
        for(KeyValue keyValue: ts){
            this.mapParameters.put(keyValue.getKey().toString(), keyValue.getValue().toString());
        }
    }

    public Boolean containsResultFor(Object o) {
        return this.getResultFor(o) != null;
    }

	public <T extends KeyValue> void addKeyValue(T keyValue) {
		this.mapParameters.put(keyValue.getKey().toString(), keyValue.getValue().toString());
	}

	public <T> void addKeyValue(T key, T value) {
		this.addKeyValue(new KeyValueImpl(key, value));
	}

	public <T> Boolean removeKeyValue(T key) {
		// TODO Auto-generated method stub
		return null;
	}

	public <T extends KeyValue> Boolean removeKeyValue(T key) {
		// TODO Auto-generated method stub
		return null;
	}
}